/********************************************************************************
* @file    bsp_exti.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-09-30
* @brief   NULL
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#include "RTE_Components.h"
#include CMSIS_device_header

#include "sys_api.h"
/* Private Includes ----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/
/* Private Variables ---------------------------------------------------------*/
bool bsp_exti_init = false;

typedef void(*bsp_gpio_exti_callback)(void *gpiox, uint16_t gpio_pin);
static bsp_gpio_exti_callback g_irq_callback;
/* Public Function Prototypes ------------------------------------------------*/
/**
 * @brief  设置外部中断NVIC
 * @param  irqn: 中断号（在typedef enum IRQn中，例如：USART1_IRQn）
 * @param  priority: 中断优先级
 */
void bsp_exit_set(uint8_t irqn, uint32_t priority)
{
    if (!bsp_exti_init)
    {
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        bsp_exti_init = true;
    }
    NVIC_InitType NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel                   = irqn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priority;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/**
 * @brief  清除外部中断设置
 * @param  irqn: 中断号（在typedef enum IRQn中，例如：USART1_IRQn）
 */
void bsp_exit_clear_set(uint8_t irqn)
{
    EXTI_ClearIntPendingBit((IRQn_Type)(irqn));
}

/**
 * @brief  清除外部中断标志位
 * @param  *gpiox: 预留
 * @param  pin: 引脚号
 */
void bsp_exit_clear_flag(void *gpiox, uint8_t pin)
{
    EXTI_ClearFlag(1 << pin);
}

/**
 * @brief  注册外部中事件回调函数
 * @param  *event: 事件函数
 */
bool bsp_gpio_exit_irq_register_callback(void *event)
{
    if (g_irq_callback != NULL)
    {
        return false;
    }
    else
    {
        g_irq_callback = (bsp_gpio_exti_callback)event;
    }
    return true;
}

/**
  * @brief  This function handles External lines 0 interrupt request.
  */
void EXTI0_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line0) != RESET)
    {
        /* Write the descriptor through the endpoint */
        /* Clear the EXTI line 0 pending bit */
        EXTI_ClearIntPendingBit(EXTI_Line0);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 0);
        }
    }
}

/**
  * @brief  This function handles External lines 1 interrupt request.
  */
void EXTI1_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line1) != RESET)
    {
        /* Write the descriptor through the endpoint */
        /* Clear the EXTI line 1 pending bit */
        EXTI_ClearIntPendingBit(EXTI_Line1);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 1);
        }
    }
}

/**
  * @brief  This function handles External lines 2 interrupt request.
  */
void EXTI2_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line2) != RESET)
    {
        /* Write the descriptor through the endpoint */
        /* Clear the EXTI line 2 pending bit */
        EXTI_ClearIntPendingBit(EXTI_Line2);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 2);
        }
    }
}

/**
  * @brief  This function handles External lines 3 interrupt request.
  */
void EXTI3_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line3) != RESET)
    {
        /* Write the descriptor through the endpoint */
        /* Clear the EXTI line 3 pending bit */
        EXTI_ClearIntPendingBit(EXTI_Line3);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 3);
        }
    }
}

/**
  * @brief  This function handles External lines 4 interrupt request.
  */
void EXTI4_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line4) != RESET)
    {
        /* Write the descriptor through the endpoint */
        /* Clear the EXTI line 4 pending bit */
        EXTI_ClearIntPendingBit(EXTI_Line4);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 4);
        }
    }
}

/**
  * @brief  This function handles External lines 9 to 5 interrupt request.
  */
void EXTI9_5_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line9) != RESET)
    {
        //<Clear the  EXTI line 9 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line9);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 9);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line8) != RESET)
    {
        //<Clear the  EXTI line 8 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line8);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 8);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line7) != RESET)
    {
        //<Clear the  EXTI line 7 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line7);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 7);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line6) != RESET)
    {
        //<Clear the  EXTI line 6 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line6);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 6);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line5) != RESET)
    {
        //<Clear the  EXTI line 5 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line5);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 5);
        }
    }
}

/**
  * @brief  This function handles External lines 15 to 10 interrupt request.
  */
void EXTI15_10_IRQHandler(void)
{
    if (EXTI_GetIntStatus(EXTI_Line15) != RESET)
    {
        //<Clear the  EXTI line 15 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line15);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 15);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line14) != RESET)
    {
        //<Clear the  EXTI line 14 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line14);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 14);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line13) != RESET)
    {
        //<Clear the  EXTI line 13 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line13);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 13);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line12) != RESET)
    {
        //<Clear the  EXTI line 12 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line12);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 12);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line11) != RESET)
    {
        //<Clear the  EXTI line 11 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line11);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 11);
        }
    }
    else if (EXTI_GetIntStatus(EXTI_Line10) != RESET)
    {
        //<Clear the  EXTI line 10 pending bit
        EXTI_ClearIntPendingBit(EXTI_Line10);
        if (g_irq_callback)
        {
            g_irq_callback(NULL, 10);
        }
    }
}
